/*
 *
 * Copyright (c) 2017 Ericsson AB Corporation, all rights reserved.
 *
 */

package com.roy.spring.multitenant.tenant;

import java.sql.Connection;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.hibernate.HibernateException;
import org.hibernate.engine.jdbc.connections.spi.MultiTenantConnectionProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

/**
 *
 *
 * @author elloxxn
 * 
 */
@Component
public class MultiTenantConnectionProviderImpl implements MultiTenantConnectionProvider {
    private static final long serialVersionUID = -5379376698684861045L;
    
    @Autowired
    private DataSource dataSource;
    
    
    @Override
    public Connection getAnyConnection() throws SQLException {
      return dataSource.getConnection();
    }

    @Override
    public void releaseAnyConnection(Connection connection) throws SQLException {
      connection.close();
    }

    @Override
    public Connection getConnection(String tenantIdentifier) throws SQLException {
      final Connection connection = getAnyConnection();
      try {
//        connection.createStatement().execute( "USE " + tenantIdentifier ); // for mysql
        if (StringUtils.hasText(tenantIdentifier))
           connection.createStatement().execute("set search_path to " + tenantIdentifier); //for postgresql.equal: set schema 'schemaname'
      }
      catch ( SQLException e ) {
        throw new HibernateException(
            "Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",
            e
            );
      }
      return connection;
    }

    @Override
    public void releaseConnection(String tenantIdentifier, Connection connection) throws SQLException {
      try {
        //connection.createStatement().execute( "USE " + TenantContext.DEFAULT_TENANT );
          connection.createStatement().execute("set schema '" + TenantContext.DEFAULT_TENANT + "'");
//        connection.createStatement().execute("set schema '" + tenantIdentifier + "'");
      }
      catch ( SQLException e ) {
        throw new HibernateException(
            "Could not alter JDBC connection to specified schema [" + tenantIdentifier + "]",
            e
            );
      }
      connection.close();
    }

    @SuppressWarnings("rawtypes")
    @Override
    public boolean isUnwrappableAs(Class unwrapType) {
      return false;
    }



    /* (non-Javadoc)
     * @see org.hibernate.service.spi.Wrapped#unwrap(java.lang.Class)
     */
    @Override
    public <T> T unwrap(Class<T> unwrapType) {
        return null;
    }

    @Override
    public boolean supportsAggressiveRelease() {
      return true;
    }
    
    /*
    @Override
    protected ConnectionProvider getAnyConnectionProvider() {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    protected ConnectionProvider selectConnectionProvider(String tenantIdentifier) {
        // TODO Auto-generated method stub
        return null;
    }*/

}
